package BLC

import (
	"blockchain/tests/part13-wallet-blockchain/wallet"
	"bytes"
	"crypto/sha256"
	"encoding/gob"
	"encoding/hex"
	"fmt"
)

const subsidy=10

type Transaction struct {
	//交易ID
	ID []byte
	//交易输入
	Vin []*TXInput
	//交易输出
	Vout []*TXOutput
}


//1.判断当前交易是否是CoinBase
func (tx *Transaction)IsCoinBase()bool{
	return len(tx.Vin)==1 && tx.Vin[0].Vout==-1 && len(tx.Vin[0].Txid)==0
}

//创建创世交易
func NewCoinBase(to,data string)*Transaction{
	if data==""{
		data=fmt.Sprintf("Reward the money to %s",to)
	}
	//创建特殊的交易输入
	vin:=&TXInput{[]byte{},-1,nil,[]byte{}}
	//交易输出
	vout:=NewTXOutput(10,to)
	//返回交易的列表
	tx:=Transaction{nil,[]*TXInput{vin},[]*TXOutput{vout}}
	tx.SetID()
	return &tx
}

//把整个交易进行sha256，得到hash值
func (tx *Transaction)SetID(){
	var buff bytes.Buffer
	var hash [32]byte

	encode:=gob.NewEncoder(&buff)
	err:=encode.Encode(tx)
	if err!=nil{
		panic(err)
	}

	hash=sha256.Sum256(buff.Bytes())
	tx.ID=hash[:]
}



//创建一个新的交易
func NewSimpleTransaction(from,to string,amount int,bc *BlockChain)*Transaction{

	wallets,_:=wallet.NewWallets()
	w:=wallets.WalletsMap[from]

	//输入
	var inputs []*TXInput
	//输出
	var outputs []*TXOutput

	//找到足够的未花费的输出
	acc,validOutput:=bc.FindUnUTXOs(from,amount)

	//判断是否够付钱
	if acc<amount{
		panic(from+"余额不足!")
	}

	//建立输入
	for txid,outs:=range validOutput{
		txID,err:=hex.DecodeString(txid)
		if err!=nil{
			panic(err)
		}

		for _,out:=range outs{
			input:=&TXInput{txID,out,nil,w.PublicKey}
			inputs=append(inputs,input)
		}
	}

	//建立输出，转账
	output:=NewTXOutput(amount,to)
	outputs=append(outputs,output)

	//找零
	output=NewTXOutput(acc-amount,from)
	outputs=append(outputs,output)

	tx:=Transaction{nil,inputs,outputs}
	tx.SetID()

	return &tx
}


